#!/usr/bin/perl

use strict;
use warnings;
use Net::SNMP qw(:snmp);
use Net::MAC;
use Net::MAC::Vendor;

my $access_point = '10.73.1.249';
my $com_ro = "as730";
my $OID_dot11ClientMacAddress = '.1.3.6.1.4.1.171.10.37.39.2.1.3.3.4.2.1.2';
my $f_syslog = "/var/log/syslog";


## Function to retrieve informations from AP
sub snmp_get {
	my ($session, $error) = Net::SNMP->session(
    	-hostname    => shift || $access_point,
    	-community   => shift || $com_ro,
    	-nonblocking => 1,
    	-translate   => [-octetstring => 0],
    	-version     => 'snmpv2c',
	);

	if (!defined $session) {
    	printf "ERROR: %s.\n", $error;
    	exit 1;
	}

	my %WIFI_CLIENT;

	my $result = $session->get_bulk_request(
    	-varbindlist    => [ $OID_dot11ClientMacAddress ],
    	-callback       => [ \&table_callback, \%WIFI_CLIENT ],
    	-maxrepetitions => 10,
	);

	if (!defined $result) {
    	printf "ERROR: %s\n", $session->error();
    	$session->close();
    	exit 1;
	}

	# Now initiate the SNMP message exchange.
	snmp_dispatcher();

	$session->close();
	# Print the results, specifically formatting ifPhysAddress.
	my @MAC_CLIENT;
	for my $oid (oid_lex_sort(keys %WIFI_CLIENT)) {
		print "TEST - ".unpack('H*',$WIFI_CLIENT{$oid})."\n";
		push(@MAC_CLIENT,unpack 'H*',$WIFI_CLIENT{$oid});
   	}
	return @MAC_CLIENT;
}

## Function to load Table from SNMP
sub table_callback
{
    my ($session, $table) = @_;
    my $list = $session->var_bind_list();
    if (!defined $list) {
        printf "ERROR: %s\n", $session->error();
        return;
    }
    # Loop through each of the OIDs in the response and assign
    # the key/value pairs to the reference that was passed with
    # the callback.  Make sure that we are still in the table
    # before assigning the key/values.
    my @names = $session->var_bind_names();
    my $next  = undef;
    while (@names) {
        $next = shift @names;
        if (!oid_base_match($OID_dot11ClientMacAddress, $next)) {
        return; # Table is done.
        }
        $table->{$next} = $list->{$next};
    }
    # Table is not done, send another request, starting at the last
    # OBJECT IDENTIFIER in the response.  No need to include the
    # calback argument, the same callback that was specified for the
    # original request will be used.
    my $result = $session->get_bulk_request(
        -varbindlist    => [ $next ],
        -maxrepetitions => 10,
    );
    if (!defined $result) {
        printf "ERROR: %s.\n", $session->error();
    }
    return;
}

## Convert MAC Addr from DLINK to IEEE
sub conv_ieee {
	my @s_array = @_;
	my @d_array;
	foreach my $s_entry (@s_array) {
		my $d_entry =  Net::MAC->new(mac => $s_entry);
		push(@d_array,$d_entry->as_IEEE());
	}
	return @d_array;
}

sub syslog_search_ip {
	my @CLIENTS = @_;
	open(SYSLOG,"<",$f_syslog) or die $!;
	my @syslog = <SYSLOG>;
	close(SYSLOG);
	my %RESULT;
	foreach my $line (@syslog)
	{
		if($line =~ m/dhcpd:\sDHCPACK/i) {
			foreach my $mac (@CLIENTS)
			{
				if( $line =~ m/.*\s(\d+\.\d+\.\d+\.\d+).*$mac.*/i) {
					my $ip = $1;
					$RESULT{$mac} = $ip;
				}
			}
		}
	}
	return %RESULT;
}
sub syslog_search_hname {
	my @CLIENTS = @_;
	open(SYSLOG,"<",$f_syslog) or die $!;
	my @syslog = <SYSLOG>;
	close(SYSLOG);
	my %RESULT;
	foreach my $line (@syslog)
	{
		if($line =~ m/dhcpd:\sDHCPACK/i) {
			foreach my $mac (@CLIENTS)
			{
				if( $line =~ m/.*\s(\d+\.\d+\.\d+\.\d+).*$mac\s\((.*)\).*/i) {
					my $ip = $1;
					my $hname = $2;
					$RESULT{$mac} = $hname;
				}
			}
		}
	}
	return %RESULT;
}

sub mac_vendor {
	my $mac = $_[0];
	my $array = Net::MAC::Vendor::lookup( $mac );
	return @{$array}[0];
}


##--------------------------------------------------------
## MAIN
##--------------------------------------------------------

print "-----------------------------------------\n";
print " Wifi : Associated Client\n";
print "-----------------------------------------\n";

my @MAC_CLIENT = &snmp_get();
@MAC_CLIENT = &conv_ieee(@MAC_CLIENT);

foreach my $mac (@MAC_CLIENT)
{ print $mac."\n"; }


my %IPS = &syslog_search_ip(@MAC_CLIENT);
my %HOSTNAME = &syslog_search_hname(@MAC_CLIENT);
my @IP = keys %IPS;

foreach my $entry (@IP) {
	my $vendor = &mac_vendor($entry);
	printf "* $entry -> %s",$IPS{$entry};
	printf " (%s)",$vendor unless !defined($vendor);
	printf " (%s)",$HOSTNAME{$entry} unless !defined($HOSTNAME{$entry});
	printf "\n";
}

print "-----------------------------------------\n";
print "\n";
exit 0;
